<?php
include_once(dirname(__FILE__).'/../../autoload.php');

/**
 * Description of DatabaseTest
 *
 * @author joona
 */
class Main_Model_DatabaseTest extends Lib_ModuleTestcase
{
    private $dbHandler;

    public function setUp()
    {
        Lib_QueryWrapper::initializeTestData();
        $this->dbHandler = new Core_Database();
        $db_host = Core_Registry::get('DB_HOST');
        $db_user = Core_Registry::get('DB_USER');
        $db_pass = Core_Registry::get('DB_PASS');
        $db_name = Core_Registry::get('DB_NAME');

        $this->dbHandler->connect($db_host, $db_user, $db_pass, $db_name);
    }

    public function test_connectToInvalidHost()
    {
        $this->setExpectedException('Core_Database_Exception');
        $this->dbHandler->connect('bogushoust', 'bogusname', null);
    }

    public function test_selectInvalidDatabase()
    {
        $this->setExpectedException('Core_Database_Exception');
        $this->dbHandler->selectDatabase('VeryInvalidDatabase');
    }

    public function test_isReady_false()
    {
        $this->assertFalse($this->dbHandler->isReady());
    }

    public function test_isReady_true()
    {
        $this->dbHandler->prepare('SELECT true FROM User');
        $this->assertTrue($this->dbHandler->isReady());
    }

    public function test_selectAndGetAll()
    {
        $expected = array(
            array('id' => 1, 'username' => 'Dude'),
            array('id' => 2, 'username' => 'JustAGuy'),
            array('id' => 3, 'username' => 'Jack'),
            array('id' => 4, 'username' => 'Mulder'),
            array('id' => 5, 'username' => 'Scully')
        );
        $this->dbHandler->prepare('SELECT id, username FROM User ORDER BY id');
        $this->dbHandler->execute();
        $actual = $this->dbHandler->getAllResults();
        $this->assertEquals($expected, $actual);
    }

    public function test_selectAndGetSingle()
    {
        $expected = 'Dude';
        $this->dbHandler->prepare('SELECT username FROM User WHERE id = 1');
        $this->dbHandler->execute();
        $this->dbHandler->fetch();
        $actual = $this->dbHandler->getResult('username');
        $this->assertEquals($expected, $actual);
    }

    public function test_selectAndGetSingles()
    {
        $expected = array(2, 'JustAGuy', null);
        $this->dbHandler->prepare('SELECT * FROM User WHERE id = 2');
        $this->dbHandler->execute();
        $this->dbHandler->fetch();
        $actual = array(
            $this->dbHandler->getResult('id'),
            $this->dbHandler->getResult('username'),
            $this->dbHandler->getResult('email')
        );
        $this->assertEquals($expected, $actual);
    }

    public function test_selectAndGetRowCount()
    {
        $this->dbHandler->prepare('SELECT * FROM User WHERE userStatusId = 1');
        $this->dbHandler->execute();

        $expected = 3;
        $actual = $this->dbHandler->getRowCount();
        $this->assertEquals($expected, $actual);
    }

    public function test_insertAndGetInsertedId()
    {
        $this->dbHandler->prepare("INSERT INTO UserStatus (status) VALUES ('Fake status')");
        $this->dbHandler->execute();

        $expected = 4;
        $actual = $this->dbHandler->insertId();
        $this->assertEquals($expected, $actual);
    }

    public function test_updateAndGetAffectedRows()
    {
        $this->dbHandler->prepare("UPDATE User SET userStatusId = 3 WHERE userGroupId = 1");
        $this->dbHandler->execute();
        $expected = 2;
        $actual = $this->dbHandler->getAffectedRows();
        $this->assertEquals($expected, $actual);
    }

    public function test_selectWithIsNull()
    {
        $this->dbHandler->prepare('SELECT COUNT(*) as \'count\' FROM User
            WHERE username = {username} AND email = {email}');
        $this->dbHandler->setRule('username', array('type' => 'string'));
        $this->dbHandler->setRule('email', array('allowNull' => true));
        $this->dbHandler->setVariable('username', 'Dude');
        $this->dbHandler->setVariable('email', null);
        $this->dbHandler->execute();
        $this->dbHandler->fetch();
        $expected = array('count' => 1);
        $actual = $this->dbHandler->getResult();
        $this->assertEquals($expected, $actual);
    }

    public function test_invalidQuery()
    {
        $this->setExpectedException('Core_Database_MysqlException');
        $this->dbHandler->prepare('Select Bogus');
        $this->dbHandler->execute();
    }
}
